package web

import (
	"gitee.com/then-go-project/go-utils/base"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	zhtranslations "github.com/go-playground/validator/v10/translations/zh"
	"go.uber.org/zap"
	"reflect"
	"strings"
)

const tagErrorMsgName = "errMsg"

var trans ut.Translator

func FormatError(errors error, paramType reflect.Type) string {
	errValues, ok := errors.(validator.ValidationErrors)
	//paramType := reflect.TypeOf(paramVal)

	if !ok || (paramType.Kind() != reflect.Struct && paramType.Kind() != reflect.Ptr) {
		base.ZapLog.Error("返回值处理失败", zap.Error(errors))
		return InternalErrMsg
	}
	if paramType.Kind() == reflect.Ptr {
		paramType = paramType.Elem()
	}

	var errResult string
	for _, err := range errValues {
		if field, exist := getFieldByStructNamespace(err.StructNamespace(), paramType); exist {
			tagValue := field.Tag.Get(tagErrorMsgName)
			if len(tagValue) > 0 {
				errResult += tagValue + "; "
			} else {
				errResult += err.Translate(trans) + "; "
			}
		} else {
			errResult += err.Translate(trans) + "; "
		}
	}
	return errResult
}

//通过迭代获取struct内部field的tag
func getFieldByStructNamespace(structNamespace string, t reflect.Type) (*reflect.StructField, bool) {
	strs := strings.Split(structNamespace, ".")
	if len(strs) < 2 {
		return nil, false
	}

	var result *reflect.StructField

	for i := 1; i < len(strs); i++ {
		tmpFieldName := strs[i]
		name, b := t.FieldByName(tmpFieldName)
		if !b {
			return nil, false
		}
		if i != len(strs)-1 {
			t = name.Type
		} else {
			result = &name
		}
	}
	return result, true
}

func init() {
	//注册翻译器
	zh := zh.New()
	uni := ut.New(zh, zh)

	trans, _ = uni.GetTranslator("zh")

	//获取gin的校验器
	validate := binding.Validator.Engine().(*validator.Validate)
	//注册翻译器
	zhtranslations.RegisterDefaultTranslations(validate, trans)
}
